/************************************************************************/
/* texture manager class												*/
/* by Georgemarios														*/
/* email: exile79@gmail.com												*/
/************************************************************************/

#pragma once

#ifdef  _DEBUG
#define IL_DEBUG
#endif

/************************************************************************/
/* includes																*/
/************************************************************************/
#include <IL/il.h>
#include <IL/ilu.h>
#include <IL/ilut.h>
#include <map>
#include <string>

/************************************************************************/
/* link with the DevIL libraries										*/
/************************************************************************/
#pragma comment(lib,"Devil.lib")
#pragma comment(lib,"ilu.lib")
#pragma comment(lib,"ilut.lib")

using namespace std;
typedef map<string,GLuint> TextureMap;

enum TextureFilter {TF_nearest,TF_linear,TF_bilinear,TF_trilinear};
/************************************************************************/
/* prototypes															*/
/************************************************************************/
bool	InitTextureManager(GLenum wrap=GL_CLAMP,TextureFilter filter=TF_linear);
bool	DeinitTextureManager();
GLuint	LoadTexture(const char*);
GLuint	LoadFont(char*);
bool	DeleteTexture(const char* );
bool	DeleteTexture(GLuint id);
bool	BindTexture(const char*);


/************************************************************************/
/* the class is singleton, meaning that there can be only				*/
/* one instance of it                                                   */
/************************************************************************/

// TODO make texture class, supporting different filters for each texture
class TextureManager
{
private:
	static TextureManager* _pinstancesingleton;
	
	TextureManager(void);
	~TextureManager(void);

	TextureMap		_textures;
//	TextureFilter	_filter;
//	GLenum			_wrap;
public:
	// allocates _pinstancesingleton if this is NULL,
	// then returns _pinstancesingleton. 
	static TextureManager *pinstance()
	{
		if(TextureManager::_pinstancesingleton==NULL)
			TextureManager::_pinstancesingleton=new TextureManager;
		return TextureManager::_pinstancesingleton;
	}
											
	static void deleteSingleton()
	{	delete _pinstancesingleton; _pinstancesingleton=NULL; }

	GLuint	GetTexture(const char* name) ;
	
	string	GetName( GLuint id ); 
	
	int		NumTextures() { return (int)_textures.size(); }

	GLuint	LoadTexture(const char* name);
	GLuint	LoadFont(char*);
	void	DeleteAllTextures();
	GLuint	BindTexture(const char* name);
	bool	DeleteTexture(const char* name);


#ifdef _DEBUG
	void	DumpTextures();
	void	TraceTextures();
#endif
};

/*
	TODO keep track how many materials requested a specified texture
	so I can request a texture delete every time a material is not 
	used (when for example a model is deleted)
*/
/*
	TODO separate texture filters for each filter (maybe a texture 
	class?)
*/
/*
	TODO optional use of DevIL, add image loaders (TGA is must)
*/
